import path from 'path'
import fs from 'fs'
import schedule from 'node-schedule'

export const scheduledJobs = {}

export const generateIds = (pluginPath) => {
  return fs
    .readdirSync(pluginPath)
    .filter((item) => fs.statSync(path.join(pluginPath, item)).isDirectory())
    .reduce((ids, item, index) => {
      ids[index + 1] = { name: item, path: path.join(pluginPath, item) }
      return ids
    }, {})
}

export const loadPlugins = (app, basePath, logger) => {
  const ids = generateIds(basePath)
  fs.writeFileSync(path.join(basePath, 'id.json'), JSON.stringify(ids, null, 2))

  Object.entries(ids).forEach(async ([id, { name: pluginFolderName, path: pluginFolderPath }]) => {
    const configPath = 'file://' + path.join(pluginFolderPath, 'config.mjs')
    if (fs.existsSync(path.join(pluginFolderPath, 'config.mjs'))) {
      try {
        const configs = await import(configPath + `?${Math.random()}`).then((module) => module.default)
        const paths = [configs.path || `/api/${pluginFolderName}`, `/api/${pluginFolderName}`, `/api/${id}`]
        paths.forEach((path) => app.use(path, (req, res) => handleRequest(req, res, configs, logger, pluginFolderName)))
        setupScheduledTasks(configs, pluginFolderName, logger)
        logger.plugin('info', `插件：${pluginFolderName} 加载成功, 监听路径: ${JSON.stringify(paths)}`)
      } catch (err) {
        logger.plugin('error', `[插件：${pluginFolderName}] 加载失败: ${err}`)
      }
    } else {
      logger.plugin('error', `[插件：${pluginFolderName}] 中未找到 config.mjs`)
    }
  })
}

const setupScheduledTasks = (configs, pluginFolderName, logger) => {
  if (configs.task) {
    if (scheduledJobs[pluginFolderName]) {
      scheduledJobs[pluginFolderName].forEach((job) => job.cancel())
    }
    scheduledJobs[pluginFolderName] = []

    const tasks = Array.isArray(configs.task) ? configs.task : [configs.task]
    tasks.forEach((task) => {
      if (task.cron) {
        const job = schedule.scheduleJob(task.cron, () => {
          if (typeof task.fnc === 'function') {
            task.fnc()
          } else {
            logger.plugin('error', `定时任务函数无效: ${task.fnc}`)
          }
        })
        scheduledJobs[pluginFolderName].push(job)
        logger.plugin('info', `插件：${pluginFolderName} 定时任务已设置, Cron：${task.cron}`)
      }
    })
  }
}

const handleRequest = (req, res, configs, logger, pluginName) => {
  try {
    if (configs.handler) {
      configs.handler(req, res)
    } else {
      logger.plugin('error', `[插件：${pluginName}] 请求未找到处理器`)
      res.status(404).send('插件处理器未定义')
    }
  } catch (error) {
    logger.plugin('error', `[插件：${pluginName}] 处理请求失败，错误: ${error}`)
    res.status(500).send('处理请求失败')
  }
}
